package io.hellsinger.navigation.screen

import android.view.ViewGroup
import androidx.collection.SparseArrayCompat
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder

class HostScreenControllerAdapter(
    private val provider: ScreenControllerProvider,
) : RecyclerView.Adapter<HostScreenControllerAdapter.ScreenControllerHolder>() {
    interface ScreenControllerProvider {
        fun getControllerCount(): Int

        fun createScreenController(position: Int): ScreenController<*>
    }

    init {
        setHasStableIds(true)
    }

    private val data = SparseArrayCompat<ScreenController<*>>()

    fun getController(position: Int): ScreenController<*> = data.valueAt(position)

    fun destroy() {
        for (i in 0 until data.size()) getController(i).onDestroy()
    }

    override fun getItemId(position: Int): Long = position.toLong()

    override fun getItemCount(): Int = provider.getControllerCount()

    override fun onViewAttachedToWindow(holder: ScreenControllerHolder) {
        holder.controller.onPrepare()
    }

    override fun onViewDetachedFromWindow(holder: ScreenControllerHolder) {
        holder.controller.onHide()
    }

    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int,
    ): ScreenControllerHolder {
        var controller = data[viewType]
        if (controller == null) {
            controller = provider.createScreenController(viewType)
            controller.onCreateView(parent.context)
            data.put(viewType, controller)
        }

        return ScreenControllerHolder(controller)
    }

    override fun onBindViewHolder(
        holder: ScreenControllerHolder,
        position: Int,
    ) {
    }

    override fun getItemViewType(position: Int): Int = position

    override fun onViewRecycled(holder: ScreenControllerHolder) {
        holder.controller.onDestroy()
    }

    class ScreenControllerHolder(
        val controller: ScreenController<*>,
    ) : ViewHolder(controller.contentView!!)
}
